﻿using System;
using System.Linq;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Framework;
using DotNetNuke.Services.Social.Messaging.Internal;
using DotNetNuke.Services.Social.Notifications;
using DotNetNuke.Web.Client.ClientResourceManagement;

namespace MessageCenterAlerts
{
    public abstract partial class Alerts : PortalModuleBase
    {
        private const string ScriptPath = "/MessageCenterAlerts.js";
        
        protected int MessageCount { get; private set; }
        protected int NotificationCount { get; private set; }
        protected string CoreMessagingBaseUrl { get; private set; }

        protected bool EnablePopupForMessages { get; private set; }
        protected bool EnablePopupForNotifications { get; private set; }
        protected bool EnableUpdateOfUsersControl { get; private set; }
        protected int MilisecondsUntilInitalDisplay { get; private set; }
        protected int MilisecondsBetweenChecks { get; private set; }
        protected int MilisecondsToDisplay { get; private set; }
        protected string Effect { get; private set; }
        protected int EffectDuration { get; private set; }

        public static class Defaults
        {
            public const bool EnablePopupForMessages = true;
            public const bool EnablePopupForNotifications = true;
            public const bool EnableUpdateOfUsersControl = true;
            public const int MilisecondsUntilInitalDisplay = 1000;
            public const int MilisecondsBetweenChecks = 10000;
            public const int MilisecondsToDisplay = 7000;
            public const string Effect = "Slide";
            public const int EffectDuration = 500;
        }

        protected int CoreMessagingTabId
        {
            get
            {
                const string cacheKey = "MessageCenterAlerts_MCTID";

                var coreMessagingTabId = (int?)DataCache.GetCache(cacheKey);

                if(!coreMessagingTabId.HasValue)
                {
                    var mc = new ModuleController();

                    var messagingModule = DesktopModuleController.GetDesktopModuleByModuleName("DotNetNuke.Modules.CoreMessaging", PortalId);

                    var tabs = new TabController().GetTabsByPortal(PortalId);

                    var coreMessagingTab = tabs.Keys.Select(tabKey => tabs[tabKey]).FirstOrDefault(tab => mc.GetTabModules(tab.TabID).Values.Any(m => m.DesktopModuleID == messagingModule.DesktopModuleID));

                    coreMessagingTabId = coreMessagingTab != null ? coreMessagingTab.TabID : 0;

                    DataCache.SetCache(cacheKey, coreMessagingTabId, DateTime.Now.AddMinutes(5));
                }

                return coreMessagingTabId.Value;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            ServicesFramework.Instance.RequestAjaxScriptSupport();
            ServicesFramework.Instance.RequestAjaxAntiForgerySupport();
            
            ClientResourceManager.RegisterScript(Page, Globals.DesktopModulePath + ModuleContext.Configuration.DesktopModule.FolderName + ScriptPath);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Don't enable the popup if we couldn't find the core messaging tab or during an asyncronous postback
            if (!Request.IsAuthenticated || CoreMessagingTabId <= 0 || Page.IsAsync)
            {
                Visible = false;
                return;
            }

            // Configure the various options that will be passed to our javascript object

            NotificationCount = NotificationsController.Instance.CountNotifications(UserInfo.UserID, PortalSettings.PortalId);
            MessageCount = InternalMessagingController.Instance.CountUnreadMessages(UserInfo.UserID, PortalSettings.PortalId);

            var tabPath = Globals.GenerateTabPath(CoreMessagingTabId, null).Replace("//", "/");

            CoreMessagingBaseUrl = string.Format("{0}tabId/{1}/userId/{2}/Default.aspx", tabPath, CoreMessagingTabId, UserId);

            var strEnablePopupForMessages = (string) Settings["EnablePopupForMessages"];
            bool enablePopupForMessages;
            if (string.IsNullOrEmpty(strEnablePopupForMessages) || !bool.TryParse(strEnablePopupForMessages, out enablePopupForMessages))
                EnablePopupForMessages = Defaults.EnablePopupForMessages;
            else
                EnablePopupForMessages = enablePopupForMessages;

            var strEnablePopupForNotifications = (string)Settings["EnablePopupForNotifications"];
            bool enablePopupForNotifications;
            if (string.IsNullOrEmpty(strEnablePopupForNotifications) || !bool.TryParse(strEnablePopupForNotifications, out enablePopupForNotifications))
                EnablePopupForNotifications = Defaults.EnablePopupForNotifications;
            else
                EnablePopupForNotifications = enablePopupForNotifications;

            var strEnableUpdateOfUsersControl = (string)Settings["EnableUpdateOfUsersControl"];
            bool enableUpdateOfUsersControl;
            if (string.IsNullOrEmpty(strEnableUpdateOfUsersControl) || !bool.TryParse(strEnableUpdateOfUsersControl, out enableUpdateOfUsersControl))
                EnableUpdateOfUsersControl = Defaults.EnableUpdateOfUsersControl;
            else
                EnableUpdateOfUsersControl = enableUpdateOfUsersControl;

            var strMilisecondsUntilInitalDisplay = (string)Settings["MilisecondsUntilInitalDisplay"];
            int milisecondsUntilInitalDisplay;
            if (string.IsNullOrEmpty(strMilisecondsUntilInitalDisplay) || !int.TryParse(strMilisecondsUntilInitalDisplay, out milisecondsUntilInitalDisplay) || milisecondsUntilInitalDisplay < 0)
                MilisecondsUntilInitalDisplay = Defaults.MilisecondsUntilInitalDisplay;
            else
                MilisecondsUntilInitalDisplay = milisecondsUntilInitalDisplay;

            var strMilisecondsBetweenChecks = (string)Settings["MilisecondsBetweenChecks"];
            int milisecondsBetweenChecks;
            if (string.IsNullOrEmpty(strMilisecondsBetweenChecks) || !int.TryParse(strMilisecondsBetweenChecks, out milisecondsBetweenChecks) || milisecondsBetweenChecks < 1000)
                MilisecondsBetweenChecks = Defaults.MilisecondsBetweenChecks;
            else
                MilisecondsBetweenChecks = milisecondsBetweenChecks;

            var strMilisecondsToDisplay = (string)Settings["MilisecondsToDisplay"];
            int milisecondsToDisplay;
            if (string.IsNullOrEmpty(strMilisecondsToDisplay) || !int.TryParse(strMilisecondsToDisplay, out milisecondsToDisplay) || milisecondsToDisplay < 2000)
                MilisecondsToDisplay = Defaults.MilisecondsToDisplay;
            else
                MilisecondsToDisplay = milisecondsToDisplay;

            Effect = (string)Settings["Effect"];
            if (string.IsNullOrEmpty(Effect))
                Effect = Defaults.Effect;

            var strEffectDuration = (string)Settings["EffectDuration"];
            int effectDuration;
            if (string.IsNullOrEmpty(strEffectDuration) || !int.TryParse(strEffectDuration, out effectDuration) || effectDuration < 0)
                EffectDuration = Defaults.EffectDuration;
            else
                EffectDuration = effectDuration;
        }

    }
}